﻿<!doctype html>
<html lang="zh">
<head>
<meta charset="utf-8">
<title>智能合约开发实战——元交易（Metatransaction），元交易合约的实现_技术宅大门</title>
<meta name="keywords" content="元交易">
<meta name="description" content="引言前一篇文章（可以看我主页哦）中提到，普通的 ETH 交易并不能够做到让用户无需 gas 费，需要交易中嵌套一个交易，即元交易，来实现免 gas 费。本文将分析开源库 OpenZeppelin/openzeppelin-contracts 中的元交易合约的实现，让你能够快速入门元交易实现细节，从而能够自己对后续更多的相关技术">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="static/css/base.css" rel="stylesheet">
<link href="static/css/m.css" rel="stylesheet">
<link href="static/css/swiper.min.css" rel="stylesheet">
<script src="static/js/jquery-3.6.0.min.js"></script>
<script src="static/js/comm.js"></script>
<!---代码高亮-->
<link href="static/css/shCoreDefault.css" rel="stylesheet" type="text/css">
<script type="text/javascript" src="static/js/shCore.js"></script>
<script type="text/javascript">
 SyntaxHighlighter.all();
</script>
</head>
<body>
<header>
  <div class="topbar"> <a href="index.html" class="logo">技术宅大门</a>
    <div class="search">
      <form action="/e/search/index.php" method="post" name="searchform" id="searchform">
        <input name="keyboard" id="keyboard" class="input_text" value="请输入关键字词" style="color: rgb(153, 153, 153);" onfocus="if(value=='请输入关键字词'){this.style.color='#000';value=''}" onblur="if(value==''){this.style.color='#999';value='请输入关键字词'}" type="text">
        <input name="show" value="title" type="hidden">
        <input name="tempid" value="1" type="hidden">
        <input name="tbname" value="news" type="hidden">
        <input name="Submit" class="input_submit" value="" type="submit">
      </form>
    </div>
  </div>
  <h2 id="mnavh"><span class="navicon"></span></h2>
</header>
<article>
  <nav>
    <div class="topnav">
      <ul id="starlist">
        <li><a href="index.html">最新文章</a></li>
        <li><a href="tuijian.html">推荐文章</a></li>
        <li><a href="hot.html">热门文章</a></li>
<li><a href="yunjisuan.html">云计算</a></li><li><a href="dashuju.html">大数据</a></li><li><a href="wulianwang.html">物联网</a></li><li><a href="qukuailian.html">区块链</a></li><li><a href="rengongzhineng.html">人工智能</a></li><li><a href="bianchengyuyan.html">编程语言</a></li><li><a href="yidongkaifa.html">移动开发</a></li> 
      </ul>
    </div>
    <em></em> </nav>
  <div class="box_l">
    <div class="weizhi"><a href="index.html">首页</a>&nbsp; / &nbsp;<a href="qukuailian.html">区块链</a> / 智能合约开发实战——元交易（Metatransaction），元交易合约的实现</div>
    <div class="con_tit">
      <h1>智能合约开发实战——元交易（Metatransaction），元交易合约的实现</h1>
      <div class="con_info"><span class="con_class">分类：<a href="qukuailian.html" target="_blank">区块链</a></span> 
        <time>2023-03-23 14:52:15</time>
        <span class="con_link"><script src="static/js/-2_7_1.js"></script></span> </div>
    </div>
    <div class="content">
<p><strong>引言</strong></p>
<p>前一篇文章（可以看我主页哦）中提到，普通的 ETH 交易并不能够做到让用户无需 gas 费，需要交易中嵌套一个交易，即元交易，来实现免 gas 费。</p>
<p>本文将分析开源库 OpenZeppelin/openzeppelin-contracts 中的元交易合约的实现，让你能够快速入门元交易实现细节，从而能够自己对后续更多的相关技术深入探索。</p>
<p><strong>前置知识概述</strong></p>
<p>元交易会涉及到 ECDSA 与 EIP712 等知识，如果你是熟手，可以跳过此节内容，直接浏览具体实现分析部分。</p>
<p><strong>Hash</strong></p>
<p>也称哈希、散列、数字摘要。通过哈希函数，可以将长短不一的信息转化为一段长度任意但可预测的（确定性的）结果。这是一类神奇的函数，可以将一大堆信息转变成一串短的，可作为摘要的数据 &ldquo;指纹&rdquo;。对于一个给定的输入而言，生成的 &ldquo;指纹&rdquo; 始终一致。如果你的原始数据中有任何细微的改动，生成的哈希值将大不相同。以太坊中采用的是 Keccak-256 算法。</p>
<p><strong>ECDSA</strong></p>
<p>在密码学中，ECDSA（Elliptic Curve Digital Signature Algorithm，椭圆曲线数字签名算法）是使用椭圆曲线密码学的数字签名算法（DSA）的一个变种。</p>
<p>主要用于对数据（比如一个文件）创建数字签名，以便于你在不破坏它的安全性的前提下对它的真实性进行验证。可以将它想象成一个实际的签名，你可以识别部分人的签名，但是你无法在别人不知道的情况下伪造它。</p>
<p>你不应该将ECDSA与用来对数据进行加密的AES（高级加密标准）相混淆。ECDSA不会对数据进行加密、或阻止别人看到或访问你的数据，它可以防止的是确保数据没有被篡改。</p>
<p>如图所示，在以太坊中，ECDSA 用于对原始数据的 hash 值进行签名及恢复。</p>
<p><img alt="0900086000300134184.20201216095126.86523331460016843504112994983392.png" src="static/picture/0161110148b15a937d53d277fb302d36.png"></p>
<p>将原始数据通过 hash 函数得到它的 hash 值后，用户 A 用自己的私钥对该 hash 值进行签名，得到 Signature（签名）。有了该签名与 hash 值，任何人都能够从中恢复出签名人的钱包地址，在这里用户 B 则恢复得到了用户 A 的钱包地址。</p>
<p><strong>EIP712</strong></p>
<p>Ethereum Improvement Proposals (EIPs)，你可以在这里查看所有的&nbsp;<strong><a href="https://eips.ethereum.org/" rel="nofollow" target="_self">EIPs</a></strong>。<strong><a href="https://eips.ethereum.org/EIPS/eip-712" rel="nofollow" target="_self">EIP712&nbsp;</a></strong>（Ethereum typed structured data hashing and signing）以太坊类型的结构化数据哈希与签名。</p>
<p>如果我们只关心字节字符串的话，签名数据是一个已经解决了的问题。但不幸的是，在现实世界中，我们关心的是复杂而有意义的信息，对结构化数据进行哈希是非常重要的，错误会导致系统安全属性的丢失。</p>
<p>此 EIP 旨在提高链上使用的链下消息签名的可用性。我们看到越来越多的人采用链下消息签名，因为它节省了 gas 费，减少了区块链上的交易数量。当前签名消息是一个不透明的十六进制字符串，显示给用户，关于组成消息的项目的上下文很少。</p>
<p><img alt="0900086000300134184.20201216095126.86523331460016843504112994983392.png" src="static/picture/32df3b0b81ec09bfc671e140eb9dc765.png"></p>
<p>EIP712 概述了一个编码数据及其结构的方案，该方案允许在签名时将数据显示给用户进行验证。下面是一个用户在签署 EIP712 消息时显示的示例。</p>
<p><img alt="0900086000300134184.20201216095126.86523331460016843504112994983392.png" src="static/picture/89495330ee636d208fd90c7b3b06fb2b.png"></p>
<p>ECDSA 是 openzeppelin 实现的一个 solidity 库，它实现了从 hash 值中恢复钱包地址的方法，将它应用在 bytes32 上，就可以直接在 bytes32 上调用 recover 方法。recover 函数签名：function recover(bytes32 hash, bytes memory signature) internal pure returns (address) 。</p>
<p>ForwardRequest 结构体定义了一个交易中用于签名的基本组成成分。与以太坊交易不同的是没有 gasPrice，因为智能合约的执行只关心 gas 的消耗。ForwardRequest 中 的 nonce 概念与以太坊类似，都是为了避免双花攻击，但这里的 nonce 仅由智能合约维护，跟普通的以太坊交易中的 nonce 无关。</p>
<p>构造函数中直接使用 EIP712 的构造函数进行初始化，EIP712 的构造函数签名为：constructor(string memory name, string memory version) ，其中 name 是合约名称，version 是合约版本，这将作为 EIP712 签名验证的一部分，它在部署时，将自动获取合约的地址、chainId 等信息。意味着，即便有相同的 ForwardRequest 结构体数据，但合约地址或区块链网络不同，也会导致签名无效。</p>
<pre>
mapping(address =&gt; uint256) private _nonces;
function getNonce(address from) public view returns (uint256) {
    return _nonces[from];
}</pre>
<p>简单理解为避免中继器（代为执行元交易的人）恶意地或无意地使用足够低的 gas 使得交易执行成功，而元交易执行失败。详情可以在&nbsp;<a href="https://ronan.eth.link/blog/ethereum-gas-dangers/" rel="nofollow">ethereum gas dangers</a>&nbsp;中学习。</p>    </div>
<script>
var paras = document.getElementsByTagName("pre");
for ( var i=0;i<paras.length;i++ ) {
    paras[i].setAttribute("class","brush:php;toolbar:false");     
}
</script>
    <div class="con_tags"><a href="-元交易.html" target="_blank">元交易</a></div>
    <div class="info-pre-next">
      <p>上一篇：<a href='qukuailian.html'>返回列表</a></p>
      <p>下一篇：<a href='qukuailian.html'>返回列表</a></p>
    </div>
    <div class="hot_news other_news">
      <div class="side_title">
        <h3>相关文章</h3>
      </div>
      <ul>
<li><a href="" title="智能合约开发实战——元交易（Metatransaction），元交易合约的实现">智能合约开发实战——元交易（Metatransaction），元交易合约的实现</a></li>      </ul>
    </div>
    <div class="blog_list">
      <div class="side_title">
        <h3>猜你喜欢</h3>
      </div>
      <ul>


<li><a href="2.html" class="blog_more">
          <h2>配置应用签名信息</h2>
          <div class="ps"><span class="ps_tj">推荐</span><span class="ps_yc">原创</span></div>
          
          <p>准备签名文件									文件名称						作用												0密钥文件（.p12文件）						用于打包项目时进行签名、获取签名证书指纹。										证书请求文件（.csr）						用于向华为申请调试证书、发布证书。												表1 需准备的签名文件清单			搭建完开发环境后，您需要使用DevEco Studio</p>
          </a>
          <div class="info"> <span class="info_class"><a href="yunjisuan.html" target="_blank">云计算</a></span><span class="info_time">2023-03-23</span><span class="info_view">9</span></div>
</li>


<li><a href="4.html" class="blog_more">
          <h2>大型物联网平台如何来保障亿级设备安全连接上云？</h2>
          <div class="ps"><span class="ps_tj">推荐</span><span class="ps_yc">原创</span></div>
           <i><img src="static/picture/smallbe1f74a105679c41ce1a12ed9e8cee691679550511.png" alt="大型物联网平台如何来保障亿级设备安全连接上云？"></i>
          <p>摘要：华为云IoT设备接入云服务（后续章节简称为“IoTDA”）提供海量设备的接入和管理能力，可以将IoT设备联接到华为云，支撑设备数据采集上云和云端下发命令给设备进行远程控制，配合华为云其他产品，帮助快速构筑物联网解决方案。</p>
          </a>
          <div class="info"> <span class="info_class"><a href="wulianwang.html" target="_blank">物联网</a></span><span class="info_time">2023-03-23</span><span class="info_view">6</span></div>
</li>


<li><a href="3.html" class="blog_more">
          <h2>爬虫时IP代理不能用？考虑以下几点原因</h2>
          <div class="ps"><span class="ps_tj">推荐</span></div>
           <i><img src="static/picture/banner1.jpg" alt="爬虫时IP代理不能用？考虑以下几点原因"></i>
          <p>代理服务商提供的IP大多数资源都是及时的。如果客户不能使用代理，IP正常访问网络，可以先检查代理IP是否有效IP生命周期不固定，受到影响IP类型，IP受质量等因素影响，有的生存时间短，几秒钟或几分钟，有的时间长，十几个小时或几天。通过测试或直接更改其他代理IP判断其不能使用的原因是比较直接快捷的方法。</p>
          </a>
          <div class="info"> <span class="info_class"><a href="dashuju.html" target="_blank">大数据</a></span><span class="info_time">2023-03-23</span><span class="info_view">19</span></div>
</li>


<li><a href="" class="blog_more">
          <h2>智能合约开发实战——元交易（Metatransaction），元交易合约的实现</h2>
          <div class="ps"><span class="ps_tj">推荐</span></div>
          
          <p>引言前一篇文章（可以看我主页哦）中提到，普通的 ETH 交易并不能够做到让用户无需 gas 费，需要交易中嵌套一个交易，即元交易，来实现免 gas 费。本文将分析开源库 OpenZeppelin/openzeppelin-contracts 中的元交易合约的实现，让你能够快速入门元交易实现细节，从而能够自己对后续更多的相关技术</p>
          </a>
          <div class="info"> <span class="info_class"><a href="qukuailian.html" target="_blank">区块链</a></span><span class="info_time">2023-03-23</span><span class="info_view">2</span></div>
</li>


<li><a href="8.html" class="blog_more">
          <h2>Leetcode 0406. 根据身高重建队列</h2>
          <div class="ps"><span class="ps_yc">原创</span></div>
          
          <p>0406. 根据身高重建队列Queue Reconstruction by Height假设有打乱顺序的一群人站成一个队列，数组 people 表示队列中一些人的属性（不一定按顺序）。每个 people[i] = [hi, ki] 表示第 i 个人的身高为 hi ，前面 正好 有 ki 个身高大于或等于 hi 的人。请你重新构造并返回输入数组 people</p>
          </a>
          <div class="info"> <span class="info_class"><a href="bianchengyuyan.html" target="_blank">编程语言</a></span><span class="info_time">2023-03-23</span><span class="info_view">9</span></div>
</li>


<li><a href="5.html" class="blog_more">
          <h2>边缘计算：盘点100个知识点</h2>
          <div class="ps"><span class="ps_tj">推荐</span></div>
          
          <p>第三代、第四代和第五代蜂窝技术。简单来说，3G 代表智能手机及其移动网络浏览器的引入；4G 是当前一代的蜂窝技术，为移动设备提供真正的宽带互联网接入；5G 蜂窝技术将为蜂窝系统提供巨大的带宽并减少延迟，支持从智能手机到自动驾驶汽车和大规模物联网的一系列设备。边缘计算被认为是 5G 的关键组成部分。</p>
          </a>
          <div class="info"> <span class="info_class"><a href="rengongzhineng.html" target="_blank">人工智能</a></span><span class="info_time">2023-03-23</span><span class="info_view">16</span></div>
</li>
      </ul>
    </div>
  </div>
  <div class="box_r">
    <div class="hot_news">
      <div class="side_title">
        <h3>最近文章</h3>
      </div>
      <ul>
        <li><a href="" target="_blank">
          <p>智能合约开发实战——元交易（Metatransaction），元交易合约的实现</p>
          </a><span>2</span></li>
      </ul>
    </div>
    <div class="tags">
      <div class="side_title"><a href="tags.html">更多</a>
        <h3>热门标签</h3>
      </div>
      <ul>
<li><a href="-WebAssembly.html">WebAssembly</a></li><li><a href="-Rust.html">Rust</a></li><li><a href="-eBPF.html">eBPF</a></li><li><a href="-OCI镜像.html">OCI镜像</a></li><li><a href="-爬虫.html">爬虫</a></li><li><a href="-IP代理.html">IP代理</a></li><li><a href="-元交易.html">元交易</a></li><li><a href="-Leetcode.html">Leetcode</a></li>      </ul>
    </div>
    <div class="tj_news">
      <div class="side_title">
        <h3>站长推荐</h3>
      </div>
      <ul>
        <li><a href="" target="_blank">
          <p>智能合约开发实战——元交易（Metatransaction），元交易合约的实现</p>
          </a></li>
      </ul>
    </div>
  </div>
</article>
<footer>
  <div class="box">
    <div class="copyright">
      <p>Copyright © 技术宅大门 
      <p>备案号 <a href="https://beian.miit.gov.cn/" target="_blank">粤ICP备2024236460号-2</a> ｜ <img src="static/picture/ga.png" alt="">｜<a href="sitemap.xml" target="_blank">网站地图</a></p>
    </div>
  </div>
</footer>
<div class="side_nav">
  <ul>
    <li><a href="about.html" title="关于博主"><i class="icon_ab"><img src="static/picture/ft_about.png" alt=""></i> </a></li>
    <li><a href="gbook.html" title="在线留言"><i class="icon_qq"><img src="static/picture/ft_qq.png" alt=""></i> </a></li>
    <li><a title="个人微信"><i class="icon_wx"><img src="static/picture/ft_ewm.png" alt=""></i><span><img src="static/picture/wx.png" alt="微信"></span> </a></li>
    <li><a href="#" class="icon-top" title="返回顶部"><i class="icon_fh"><img src="static/picture/ft_top.png" alt=""></i> </a></li>
  </ul>
</div><script src="static/js/js.js"></script></body>
</html>